// Released in the Public Domain. http://creativecommons.org/licenses/publicdomain/
package org.xi8ix.async.spi;

import org.xi8ix.async.Statistics;

/**
 * @author Iain Shigeoka
 */
public class StatisticsImpl implements Statistics {

    // ----------------------------
    // Time information
    // ----------------------------
    protected long startTime;
    protected long resetTime;

    // ----------------------------
    // Send/recv tracking
    // ----------------------------
    /** The time in milliseconds since the epoch since we last sent data to peer. */
    private long lastSend;
    /** The time in milliseconds since the epoch since we last received data from the peer. */
    private long lastRecv;
    /** Total time in milliseconds sent data sat in the queue. */
    private long timeToFirstSend;
    /** The number of packets handled. Average time in queue can be obtained by dividing time by count. */
    private long timeToFirstSendCount;

    // ----------------------------
    // Byte count statistics
    // ----------------------------
    /** The number of incoming bytes since the last reset. */
    private long inboundBytes;
    /** The number of incoming packets read since the last reset. */
    private long inboundPackets;
    /** The number of outgoing bytes since the last reset. */
    private long outboundBytes;
    /** The number of outgoing packets written since the last reset. */
    private long outboundPackets;

    public StatisticsImpl() {
        lastSend = lastRecv = resetTime = startTime = System.currentTimeMillis();
    }

    /**
     * Get the time in milliseconds since the epoch when this port was created.
     *
     * @return the time in milliseconds since the epoch when this port was created.
     */
    public long getStartTime() {
        return startTime;
    }

    /**
     * Get the time in milliseconds since the epoch when the statistics for the port was last reset.
     *
     * @return the time in milliseconds since the epoch when the statistics for the port was last reset.
     */
    public long getResetTime() {
        return resetTime;
    }

    /**
     * Resets the resetTime to 'now' and all statistics to zero.
     */
    public void resetByteStatistics() {
        resetTime = System.currentTimeMillis();
        inboundBytes = inboundPackets = outboundBytes = outboundPackets = 0;
    }

    public void resetSendTimeStatistics() {
        timeToFirstSend = timeToFirstSendCount = 0;
    }

    public long getLastSend() {
        return lastSend;
    }

    public void setLastSend(long lastSend) {
        this.lastSend = lastSend;
    }

    public long getLastRecv() {
        return lastRecv;
    }

    public void setLastRecv(long lastRecv) {
        this.lastRecv = lastRecv;
    }

    public long getTimeToFirstSend() {
        return timeToFirstSend;
    }

    public void addTimeToFirstSend(long timeToFirstSend) {
        this.timeToFirstSend += timeToFirstSend;
        this.timeToFirstSendCount ++;
    }

    public void setTimeToFirstSend(long timeToFirstSend) {
        this.timeToFirstSend = timeToFirstSend;
    }

    public long getTimeToFirstSendCount() {
        return timeToFirstSendCount;
    }

    public void setTimeToFirstSendCount(long timeToFirstSendCount) {
        this.timeToFirstSendCount = timeToFirstSendCount;
    }

    public long getInboundBytes() {
        return inboundBytes;
    }

    public void addInboundBytes(long inboundBytes, int packets) {
        this.inboundBytes += inboundBytes;
        this.inboundPackets += packets;
    }

    public void setInboundBytes(long inboundBytes) {
        this.inboundBytes = inboundBytes;
    }

    public long getInboundPackets() {
        return inboundPackets;
    }

    public void setInboundPackets(long inboundPackets) {
        this.inboundPackets = inboundPackets;
    }

    public long getOutboundBytes() {
        return outboundBytes;
    }

    public void addOutboundBytes(long outboundBytes, int packets) {
        this.outboundBytes += outboundBytes;
        this.outboundPackets += packets;
    }

    public void setOutboundBytes(long outboundBytes) {
        this.outboundBytes = outboundBytes;
    }

    public long getOutboundPackets() {
        return outboundPackets;
    }

    public void setOutboundPackets(long outboundPackets) {
        this.outboundPackets = outboundPackets;
    }
}
